package com.ruoyi.web.controller.tool;

/**
 * @author zhouwenhao
 * @date 2024/7/5
 * @dec 描述
 */
import com.opencsv.CSVReader;
import com.ruoyi.common.MdbUtils;

import com.ruoyi.common.utils.SnowflakeIdUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.control.domain.*;
import com.ruoyi.control.mapper.*;
import com.ruoyi.control.service.IDimianHistoryService;
import com.ruoyi.control.service.IDimianfenzhanHistoryService;
import com.ruoyi.control.service.IJingxiaHistoryService;
import com.ruoyi.control.service.IJingxiafenzhanHistoryService;
import com.ruoyi.control.water.domain.Dimian;
import com.ruoyi.control.water.domain.Dimianfenzhan;
import com.ruoyi.control.water.domain.Jingxia;
import com.ruoyi.control.water.domain.Jingxiafenzhan;
import com.ruoyi.control.water.service.IDimianService;
import com.ruoyi.control.water.service.IDimianfenzhanService;
import com.ruoyi.control.water.service.IJingxiaService;
import com.ruoyi.control.water.service.IJingxiafenzhanService;
import com.ruoyi.kepServer.aircompressor.domain.Aircompressor;
import com.ruoyi.kepServer.aircompressor.mapper.AircompressorMapper;
import com.ruoyi.kepServer.centralpumphouse.domain.Centralpumphouse;
import com.ruoyi.kepServer.centralpumphouse.mapper.CentralpumphouseMapper;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.identity.AnonymousProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.IdentityProvider;
import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscriptionManager;
import org.eclipse.milo.opcua.sdk.client.nodes.UaNode;
import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedDataItem;
import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedSubscription;
import org.eclipse.milo.opcua.stack.core.AttributeId;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.UaException;
import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
import org.eclipse.milo.opcua.stack.core.types.builtin.*;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.enumerated.MonitoringMode;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
import org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemCreateRequest;
import org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters;
import org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Component;
import oshi.driver.mac.net.NetStat;

import java.io.*;
import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;


@Component
public class FolderCreationRunner implements ApplicationRunner {
    @Autowired
    private AircompressorMapper aircompressorMapper;
    @Autowired
    private CentralpumphouseMapper centralpumphouseMapper;
    @Autowired
    private AircompressorHistoryMapper aircompressorHistoryMapper;
    @Autowired
    private CentralpumphouseHistoryMapper centralpumphouseHistoryMapper;
    @Autowired
    private GasDrainagePumpRoomMapper gasDrainagePumpRoomMapper;
    @Autowired
    private GasDrainagePumpRoomHistoryMapper gasDrainagePumpRoomHistoryMapper;
    @Autowired
    private Mainventilator1HistoryMapper mainventilator1HistoryMapper;
    @Autowired
    private Mainventilator2HistoryMapper mainventilator2HistoryMapper;
    @Autowired
    private MainventilatorTwoMapper mainventilatorTwoMapper;
    @Autowired
    private MainventilatorOneMapper mainventilatorOneMapper;
    @Autowired
    private BeltMapper beltMapper;
    @Autowired
    private BeltHistoryMapper beltHistoryMapper;
    @Autowired
    private ElectricityMapper electricityMapper;
    @Autowired
    private ElectricityHistoryMapper electricityHistoryMapper;
    @Autowired
    private ProducingNitrogenMapper producingNitrogenMapper;
    @Autowired
    private ProducingNitrogenHistoryMapper producingNitrogenHistoryMapper;
    @Autowired
    private AuxiliaryFanMapper auxiliaryFanMapper;
    @Autowired
    private AuxiliaryFanHistoryMapper auxiliaryFanHistoryMapper;
    @Autowired
    private IDimianfenzhanHistoryService dimianfenzhanHistoryServiceService;
    @Autowired
    private IDimianHistoryService dimianHistoryService;
    @Autowired
    private IJingxiafenzhanHistoryService jingxiafenzhanHistoryService;
    @Autowired
    private IJingxiaHistoryService jingxiaHistoryService;
    @Autowired
    private IDimianfenzhanService dimianfenzhanService;
    @Autowired
    private IDimianService dimianService;
    @Autowired
    private IJingxiafenzhanService jingxiafenzhanService;
    @Autowired
    private IJingxiaService jingxiaService;

    private final static String  endPointUrl = "opc.tcp://172.16.8.17:49320";
    //private final static String  endPointUrl = "opc.tcp://127.0.0.1:49320";
    private final static String  endPointUrlBelt = "opc.tcp://172.16.8.234:45321";
    //private final  String hydrology = "C:/Users/pengjie/Desktop/hydrology";
    //private final  String hydrologyCopy = "C:/Users/pengjie/Desktop/hydrology/backup/";
    private final  String hydrology = "/home/deploy/ftp/hydrology";
    private final  String hydrologyCopy = "/home/deploy/backup/";
    // 假设我们有一个要订阅的节点列表
    private  List<String> keyToSubscribe1 = new ArrayList<>();
    private  List<String> keyToSubscribe2 = new ArrayList<>();
    private  List<String> keyToSubscribe3 = new ArrayList<>();
    private  List<String> keyToSubscribe4 = new ArrayList<>();
    private  List<String> keyToSubscribe5 = new ArrayList<>();
    private  List<String> keyToSubscribe6 = new ArrayList<>();
    private  List<String> keyToSubscribe7 = new ArrayList<>();
    private  List<String> keyToSubscribe8 = new ArrayList<>();
    private  List<String> keyToSubscribe9 = new ArrayList<>();
    private  List<String> keyToSubscribe10 = new ArrayList<>();
    OpcUaClient clientLocalhost1 = null;
    OpcUaClient clientLocalhost2 = null;
    OpcUaClient clientLocalhost3 = null;
    OpcUaClient clientLocalhost5 = null;
    OpcUaClient clientLocalhost6 = null;
    OpcUaClient clientLocalhost7 = null;
    OpcUaClient clientLocalhost8 = null;
    OpcUaClient clientLocalhost9 = null;
    OpcUaClient clientLocalhost10 = null;
    OpcUaClient clientLocalhost4 = null;

    SnowflakeIdUtils snowflakeIdUtils = new SnowflakeIdUtils(5, 8);

    @Value("${collector.kepserver.enable:true}")
    private boolean enable;
    @Value("${collector.hydrology.enable:true}")
    private boolean enableHydrology;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        if (enable){
            keyToSubscribe1.add("中央水泵房");
            keyToSubscribe5.add("1-6瓦斯抽放泵");
            keyToSubscribe5.add("7-10瓦斯抽放泵");
            keyToSubscribe5.add("瓦斯抽放泵房2");
            keyToSubscribe5.add("瓦斯抽放泵房3");
            keyToSubscribe6.add("空压机");
            keyToSubscribe2.add("局扇1");
            keyToSubscribe2.add("局扇2");
            keyToSubscribe2.add("局扇3");
            keyToSubscribe2.add("局扇4");
            keyToSubscribe7.add("1号主扇风机");
            keyToSubscribe7.add("2号主扇风机");
            keyToSubscribe10.add("地面变电所");
            keyToSubscribe10.add("井下变电所高压一");
            keyToSubscribe9.add("地面变电所");
            keyToSubscribe9.add("井下变电所");
            keyToSubscribe10.add("制氮");
//            keyToSubscribe3.add("皮带1");
//            keyToSubscribe3.add("皮带2");
//            keyToSubscribe4.add("皮带3");
//            keyToSubscribe4.add("皮带4");
            clientLocalhost1 = createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
            clientLocalhost2 = createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
            clientLocalhost5 =createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
            clientLocalhost6 =createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
            clientLocalhost7 =createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
            clientLocalhost8 =createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
            clientLocalhost9 =createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
            clientLocalhost10 =createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");

//            clientLocalhost3 =createClientNewEndpoint(endPointUrlBelt,  "ua", "cdtu0123456789");
//            clientLocalhost4 = createClientNewEndpoint(endPointUrlBelt, "ua", "cdtu0123456789");

            ScheduledExecutorService schedulerOpc1 = Executors.newScheduledThreadPool(1);
            schedulerOpc1.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        if (clientLocalhost1 != null){
                            managedSubscriptionEvent(clientLocalhost1, keyToSubscribe1);
                        }else {
                            clientLocalhost1=createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 3, TimeUnit.SECONDS);
            ScheduledExecutorService schedulerOpc2 = Executors.newScheduledThreadPool(1);
            schedulerOpc2.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        if (clientLocalhost2 != null){
                            managedSubscriptionEvent(clientLocalhost2, keyToSubscribe2);
                        }else {
                            clientLocalhost2=createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 3, TimeUnit.SECONDS);

//            ScheduledExecutorService schedulerOpc3 = Executors.newScheduledThreadPool(1);
//            schedulerOpc3.scheduleAtFixedRate(() -> {
//                CompletableFuture.runAsync(() -> {
//                    try {
//                        if (clientLocalhost3 != null){
//                            managedSubscriptionEvent(clientLocalhost3, keyToSubscribe3);
//                        }else {
//                            clientLocalhost3=createClientNewEndpoint(endPointUrlBelt,  "ua", "cdtu0123456789");
//                        }
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
//            }, 0, 5, TimeUnit.SECONDS);
//            ScheduledExecutorService schedulerOpc4 = Executors.newScheduledThreadPool(1);
//            schedulerOpc4.scheduleAtFixedRate(() -> {
//                CompletableFuture.runAsync(() -> {
//                    try {
//                        if (clientLocalhost4 != null){
//                            managedSubscriptionEvent(clientLocalhost4, keyToSubscribe4);
//                        }else {
//                            clientLocalhost4=createClientNewEndpoint(endPointUrlBelt,  "ua", "cdtu0123456789");
//                        }
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
//            }, 0, 5, TimeUnit.SECONDS);

            ScheduledExecutorService schedulerOpc5 = Executors.newScheduledThreadPool(1);
            schedulerOpc5.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        if (clientLocalhost5 != null){
                            managedSubscriptionEvent(clientLocalhost5, keyToSubscribe5);
                        }else {
                            clientLocalhost5=createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 3, TimeUnit.SECONDS);
            ScheduledExecutorService schedulerOpc6 = Executors.newScheduledThreadPool(1);
            schedulerOpc6.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        if (clientLocalhost6 != null){
                            managedSubscriptionEvent(clientLocalhost6, keyToSubscribe6);
                        }else {
                            clientLocalhost6=createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 3, TimeUnit.SECONDS);
            ScheduledExecutorService schedulerOpc7 = Executors.newScheduledThreadPool(1);
            schedulerOpc7.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        if (clientLocalhost7 != null){
                            managedSubscriptionEvent(clientLocalhost7, keyToSubscribe7);
                        }else {
                            clientLocalhost7=createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 3, TimeUnit.SECONDS);
            ScheduledExecutorService schedulerOpc8 = Executors.newScheduledThreadPool(1);
            schedulerOpc8.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        if (clientLocalhost8 != null){
                            managedSubscriptionEvent(clientLocalhost8, keyToSubscribe8);
                        }else {
                            clientLocalhost8=createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 3, TimeUnit.SECONDS);
            ScheduledExecutorService schedulerOpc9 = Executors.newScheduledThreadPool(1);
            schedulerOpc9.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        if (clientLocalhost9 != null){
                            managedSubscriptionEvent(clientLocalhost9, keyToSubscribe9);
                        }else {
                            clientLocalhost9=createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 3, TimeUnit.SECONDS);
            ScheduledExecutorService schedulerOpc10 = Executors.newScheduledThreadPool(1);
            schedulerOpc10.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        if (clientLocalhost10 != null){
                            managedSubscriptionEvent(clientLocalhost10, keyToSubscribe10);
                        }else {
                            clientLocalhost10=createClientNewEndpoint(endPointUrl, "ua", "cdtu0123456789");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 3, TimeUnit.SECONDS);

        }
        if (enableHydrology){
            ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            scheduler.scheduleAtFixedRate(() -> {
                CompletableFuture.runAsync(() -> {
                    try {
                        File folder = new File(hydrology);
                        File[] fileArr = folder.listFiles((dir, name) -> name.endsWith(".mdb")); // 只列出.mdb文件
                        if ( fileArr !=null && fileArr.length != 0) {
                            File[] limitedFiles = Arrays.copyOfRange(fileArr, 0, Math.min(fileArr.length, 100));
                            for (File file : limitedFiles) {
                                if( file.exists()){
                                    String fileName = file.getName();
                                    Files.copy(Paths.get(hydrology + "/" + fileName),Paths.get(hydrologyCopy + fileName));
                                    Files.delete(Paths.get(hydrology + "/" + fileName));
                                }
                            }
                            for (File file : limitedFiles) {
                                String fileName = file.getName();
                                readAccessDiMianFenZhan(hydrologyCopy+fileName);
                                readAccessDiMian(hydrologyCopy+fileName);
                                readAccessJingxiaFenZhan(hydrologyCopy+fileName);
                                readAccessJingxia(hydrologyCopy+fileName);
                            }
                            for (File file : limitedFiles) {
                                String fileName = file.getName();
                                // 在finally块中尝试删除文件，使用重试机制
                                boolean fileDeleted = deleteFileWithRetry(hydrologyCopy+fileName, 100, 10, TimeUnit.SECONDS);
                                if (!fileDeleted) {
                                    // 如果文件仍未被删除，可以选择记录日志、抛出异常或采取其他措施
                                    // 根据需要，可以选择抛出异常或进行其他错误处理
                                    // throw new RuntimeException("无法删除MDB文件");
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, Executors.newSingleThreadExecutor()); // 这里使用了临时的单线程执行器，但通常您会希望使用一个更持久的执行器
            }, 0, 50, TimeUnit.SECONDS);
        }

    }
    /**
     * 创建OPC UA客户端
     */
    private OpcUaClient createClient() throws Exception {
        //opc ua服务端地址
        Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security");
        Files.createDirectories(securityTempDir);
        if (!Files.exists(securityTempDir)) {
            throw new Exception("unable to create security dir: " + securityTempDir);
        }
        return OpcUaClient.create(endPointUrl, endpoints -> endpoints.stream().filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri())).findFirst(), configBuilder -> configBuilder.setApplicationName(LocalizedText.english("eclipse milo opc-ua client")).setApplicationUri("urn:eclipse:milo:examples:client")
                //访问方式
                //.setIdentityProvider(new AnonymousProvider())
                .setIdentityProvider(new UsernameProvider("ua", "cdtu0123456789"))
                .setRequestTimeout(UInteger.valueOf(500)).build());
    }
    /**
     * 创建OPC UA客户端（皮带）
     */
    private OpcUaClient createClientBelt() throws Exception {
        Path securityTempDir = Paths.get(System.getProperty("java.io.tmpdir"), "security");
        Files.createDirectories(securityTempDir);
        if (!Files.exists(securityTempDir)) {
            throw new Exception("unable to create security dir: " + securityTempDir);
        }
        return OpcUaClient.create(endPointUrlBelt,
                endpoints ->
                        endpoints.stream()
                                .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
                                .findFirst(),
                configBuilder ->
                        configBuilder
                                .setApplicationName(LocalizedText.english("eclipse milo opc-ua client"))
                                .setApplicationUri("urn:eclipse:milo:examples:client")
                                //访问方式
                                .setIdentityProvider(new AnonymousProvider())
                                .setRequestTimeout(UInteger.valueOf(5000))
                                .build()
        );
    }
    /**
     * 遍历树形节点
     *
     * @param client OPC UA客户端
     * @param uaNode 节点
     * @throws Exception
     */
    private  void browseNode(OpcUaClient client, UaNode uaNode) throws Exception {
        List<? extends UaNode> nodes;
        if (uaNode == null) {
            nodes = client.getAddressSpace().browseNodes(Identifiers.ObjectsFolder);
        } else {
            nodes = client.getAddressSpace().browseNodes(uaNode);
        }
        for (UaNode nd : nodes) {
            //排除系统行性节点，这些系统性节点名称一般都是以"_"开头
            if (Objects.requireNonNull(nd.getBrowseName().getName()).contains("_")) {
                continue;
            }
            browseNode(client, nd);
        }
    }

    /**
     * 读取节点数据
     *
     * @param client OPC UA客户端
     * @throws Exception
     */
    private  void readNode(OpcUaClient client) throws Exception {
        int namespaceIndex = 2;
        String identifier = "通道 1.设备 1.标记 1";
        //节点
        NodeId nodeId = new NodeId(namespaceIndex, identifier);
        //读取节点数据
        DataValue value = client.readValue(0.0, TimestampsToReturn.Neither, nodeId).get();
        //标识符
        identifier = String.valueOf(nodeId.getIdentifier());
    }

    /**
     * 写入节点数据
     *
     * @param client
     * @throws Exception
     */
    private  void writeNodeValue(OpcUaClient client) throws Exception {
        //节点
        NodeId nodeId = new NodeId(2, "通道 1.设备 1.标记 4");
        Short i = 48;
        //创建数据对象,此处的数据对象一定要定义类型，不然会出现类型错误，导致无法写入
        DataValue nowValue = new DataValue(new Variant(i), null, null);
        //写入节点数据
        StatusCode statusCode = client.writeValue(nodeId, nowValue).join();
    }

    /**
     * 订阅(单个)
     *
     * @param client
     * @throws Exception
     */
    private  void subscribe(OpcUaClient client) throws Exception {
        AtomicInteger a = new AtomicInteger();
        //创建发布间隔1000ms的订阅对象
        client.getSubscriptionManager().createSubscription(1000.0).thenAccept(t -> {
            //节点
            NodeId nodeId = new NodeId(1, "h|过程值归档\\1#主机1#皮带停/HA Config/AggregateConfiguration/PercentDataBad");
            ReadValueId readValueId = new ReadValueId(nodeId, AttributeId.Value.uid(), null, null);
            //创建监控的参数
            MonitoringParameters parameters = new MonitoringParameters(UInteger.valueOf(a.getAndIncrement()), 1000.0, null, UInteger.valueOf(10), true);
            //创建监控项请求
            //该请求最后用于创建订阅。
            MonitoredItemCreateRequest request = new MonitoredItemCreateRequest(readValueId, MonitoringMode.Reporting, parameters);
            List<MonitoredItemCreateRequest> requests = new ArrayList<>();
            requests.add(request);
            //创建监控项，并且注册变量值改变时候的回调函数。
            t.createMonitoredItems(TimestampsToReturn.Both, requests, (item, id) -> item.setValueConsumer((it, val) -> {
            }));
        }).get();

        //持续订阅
        Thread.sleep(Long.MAX_VALUE);
    }

    /**
     * 批量订阅
     *
     * @param client
     * @throws Exception
     */
//  private  void managedSubscriptionEvent(OpcUaClient client) throws Exception {
//      final CountDownLatch eventLatch = new CountDownLatch(1);
//
//      //处理订阅业务
//      handlerNode(client);
//
//      //持续监听
//      eventLatch.await();
//  }

    /**
     * 处理订阅业务
     *
     * @param client OPC UA客户端
     */
    private void handlerNode(OpcUaClient client,List<String> list) {
        try {
            if (list.size() !=0){
                //创建订阅
                ManagedSubscription subscription = ManagedSubscription.create(client);

                Map<String,List<String>> map=new HashMap<>();
                for (String name : list){
                    //你所需要订阅的key  格式（n=***;s=***）
                    List<String> keyStr = new ArrayList<>();
                    //获得tag name                    C:/Users/pengjie/Desktop/kepserver/   /home/deploy/kepserver/
                    List<String> nameList=getCsvName("/home/deploy/kepserver/"+name+".csv");
                    keyStr=nameList.stream().map(item->{
                        String keyName="";
                        if ("皮带1".equals(name) || "皮带2".equals(name) || "皮带3".equals(name) || "皮带4".equals(name) ){
                            if ("皮带1".equals(name) || "皮带2".equals(name) || "皮带3".equals(name) || "皮带4".equals(name)){
                                keyName="皮带.皮带."+item;
                            }else {
                                keyName=item;
                            }
                        }else {
                            if ("地面变电所".equals(name) || "井下变电所".equals(name)){
                                keyName="煤矿1."+name+"."+item;
                            }else {
                                keyName="煤矿."+name+"."+item;
                            }
                        }
                        return keyName;
                    }).collect(Collectors.toList());
                    map.put(name,keyStr);
                }
                for (Map.Entry<String, List<String>> entry : map.entrySet()){
                    String key = entry.getKey();    // 获取键
                    List<String> value = entry.getValue();  // 获取值
                    List<NodeId> nodeIdList = new ArrayList<>();
                    for (String s : value) {
                        if (s.contains("t|") || s.contains("h|")) {
                            nodeIdList.add(new NodeId(1, s));
                        } else {
                            nodeIdList.add(new NodeId(2, s));
                        }
                    }
//                long start = System.currentTimeMillis();
//                System.out.println("$$$$$$$$$$$$$$$$"+start +"$$$$$$"+list.size());
                    CompletableFuture<List<DataValue>> listTest=client.readValues(0.0,TimestampsToReturn.Both,nodeIdList);
                    // 处理读取结果
                    listTest.thenAccept(dataValues -> {
                        //创建批量列表
                        List<Belt> beltList1=new ArrayList<>();
                        List<BeltHistory> beltHistoryList1=new ArrayList<>();
                        List<Belt> beltList2=new ArrayList<>();
                        List<BeltHistory> beltHistoryList2=new ArrayList<>();
                        List<Belt> beltList3=new ArrayList<>();
                        List<BeltHistory> beltHistoryList3=new ArrayList<>();
                        List<Belt> beltList4=new ArrayList<>();
                        List<BeltHistory> beltHistoryList4=new ArrayList<>();

                        List<Electricity> electricityList1=new ArrayList<>();
                        List<ElectricityHistory> electricityHistoryList1=new ArrayList<>();
                        List<Electricity> electricityList2=new ArrayList<>();
                        List<ElectricityHistory> electricityHistoryList2=new ArrayList<>();
                        List<Electricity> electricityList3=new ArrayList<>();
                        List<ElectricityHistory> electricityHistoryList3=new ArrayList<>();
                        List<Electricity> electricityList4=new ArrayList<>();
                        List<ElectricityHistory> electricityHistoryList4=new ArrayList<>();

                        List<MainventilatorOne> mainventilatorOneList=new ArrayList<>();
                        List<Mainventilator1History> mainventilator1HistoryList=new ArrayList<>();
                        List<MainventilatorOne> mainventilatorOneList1=new ArrayList<>();
                        List<Mainventilator1History> mainventilator1HistoryList1=new ArrayList<>();


                        List<Centralpumphouse> centralpumphouseList=new ArrayList<>();
                        List<CentralpumphouseHistory> centralpumphouseHistoryList=new ArrayList<>();

                        List<GasDrainagePumpRoom> gasDrainagePumpRoomList=new ArrayList<>();
                        List<GasDrainagePumpRoomHistory> gasDrainagePumpRoomHistoryList=new ArrayList<>();
                        List<GasDrainagePumpRoom> gasDrainagePumpRoomList1=new ArrayList<>();
                        List<GasDrainagePumpRoomHistory> gasDrainagePumpRoomHistoryList1=new ArrayList<>();

                        List<Aircompressor> aircompressorList=new ArrayList<>();
                        List<AircompressorHistory> aircompressorHistoryList=new ArrayList<>();


                        List<AuxiliaryFan> auxiliaryFanList1=new ArrayList<>();
                        List<AuxiliaryFanHistory> auxiliaryFanHistoryList1=new ArrayList<>();
                        List<AuxiliaryFan> auxiliaryFanList2=new ArrayList<>();
                        List<AuxiliaryFanHistory> auxiliaryFanHistoryList2=new ArrayList<>();
                        List<AuxiliaryFan> auxiliaryFanList3=new ArrayList<>();
                        List<AuxiliaryFanHistory> auxiliaryFanHistoryList3=new ArrayList<>();
                        List<AuxiliaryFan> auxiliaryFanList4=new ArrayList<>();
                        List<AuxiliaryFanHistory> auxiliaryFanHistoryList4=new ArrayList<>();

                        List<ProducingNitrogen> producingNitrogenList=new ArrayList<>();
                        List<ProducingNitrogenHistory> producingNitrogenHistoryList=new ArrayList<>();

                        List<CompletableFuture<Void>> futures = new ArrayList<>();

                        for (int i = 0; i < dataValues.size(); i++) {
                            DataValue dataValue = dataValues.get(i);
                            // 检查状态码以确定读取是否成功
                            String originalString="";
                            String tagName="";
                            if (dataValue.getStatusCode().isGood()) {
                                // 获取并打印值
                                String valueStr = dataValue.getValue().getValue().toString();
                                String str=  nodeIdList.get(i).toString();
                                int startIndex = str.indexOf("id=");
                                if (startIndex != -1) {
                                    startIndex += "id=".length(); // 移动到 "id=" 之后

                                    // 查找 "}" 的位置
                                    int endIndex = str.indexOf("}", startIndex);
                                    if (endIndex != -1) {
                                        // 提取子字符串
                                        originalString = str.substring(startIndex, endIndex);
                                    } else {
                                    }
                                } else {
                                    System.out.println("'id=' not found in the string");
                                }

                                if (originalString.contains("t|") || originalString.contains("h|")){
                                    tagName=originalString;
                                }else {
                                    //寻找数据表
                                    int firstDotIndex = originalString.indexOf(".");
                                    int secondDotIndex = originalString.indexOf(".", firstDotIndex + 1);
                                    // 然后，我们截取这两个"."之间的部分
                                    String resultString = originalString.substring(firstDotIndex + 1, secondDotIndex);
                                    //寻找数据名
                                    tagName = originalString.substring(secondDotIndex + 1, originalString.length());
//                        }
                                }
                                Date data=new Date();
                                switch (key){
                                    case  "中央水泵房":
                                        Centralpumphouse centralpumphouse = new Centralpumphouse();
                                        centralpumphouse.setUpdateTime(new Date());
                                        centralpumphouse.setTagName(tagName);
                                        centralpumphouse.setValue(valueStr);
                                        centralpumphouseList.add(centralpumphouse);
                                        CentralpumphouseHistory centralpumphouseHistory = new CentralpumphouseHistory();
                                        centralpumphouseHistory.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        centralpumphouseHistory.setTagName(tagName);
                                        centralpumphouseHistory.setValue(valueStr);
                                        centralpumphouseHistory.setUpdateTime(new Date());
                                        centralpumphouseHistoryList.add(centralpumphouseHistory);
                                        break;
                                    case  "1-6瓦斯抽放泵":
                                        GasDrainagePumpRoom gasDrainagePumpRoom = new GasDrainagePumpRoom();
                                        gasDrainagePumpRoom.setUpdateTime(new Date());
                                        gasDrainagePumpRoom.setTagName(tagName);
                                        gasDrainagePumpRoom.setValue(valueStr);
                                        gasDrainagePumpRoomList.add(gasDrainagePumpRoom);
                                        GasDrainagePumpRoomHistory gasDrainagePumpRoomHistory = new GasDrainagePumpRoomHistory();
                                        gasDrainagePumpRoomHistory.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        gasDrainagePumpRoomHistory.setTagName(tagName);
                                        gasDrainagePumpRoomHistory.setValue(valueStr);
                                        gasDrainagePumpRoomHistory.setUpdateTime(new Date());
                                        gasDrainagePumpRoomHistoryList.add(gasDrainagePumpRoomHistory);
                                        break;
                                    case  "7-10瓦斯抽放泵":
                                        GasDrainagePumpRoom gasDrainagePumpRoom1 = new GasDrainagePumpRoom();
                                        gasDrainagePumpRoom1.setUpdateTime(new Date());
                                        gasDrainagePumpRoom1.setTagName(tagName);
                                        gasDrainagePumpRoom1.setValue(valueStr);
                                        gasDrainagePumpRoomList1.add(gasDrainagePumpRoom1);
                                        GasDrainagePumpRoomHistory gasDrainagePumpRoomHistory1 = new GasDrainagePumpRoomHistory();
                                        gasDrainagePumpRoomHistory1.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        gasDrainagePumpRoomHistory1.setTagName(tagName);
                                        gasDrainagePumpRoomHistory1.setValue(valueStr);
                                        gasDrainagePumpRoomHistory1.setUpdateTime(new Date());
                                        gasDrainagePumpRoomHistoryList1.add(gasDrainagePumpRoomHistory1);
                                        break;
                                    case  "空压机":
                                        Aircompressor aircompressor = new Aircompressor();
                                        aircompressor.setUpdateTime(new Date());
                                        aircompressor.setTagName(tagName);
                                        aircompressor.setValue(valueStr);
                                        aircompressorList.add(aircompressor);
                                        AircompressorHistory aircompressorHistory = new AircompressorHistory();
                                        aircompressorHistory.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        aircompressorHistory.setTagName(tagName);
                                        aircompressorHistory.setValue(valueStr);
                                        aircompressorHistory.setUpdateTime(new Date());
                                        aircompressorHistoryList.add(aircompressorHistory);
                                        break;
                                    case  "局扇1":
                                        AuxiliaryFan auxiliaryFan1 = new AuxiliaryFan();
                                        auxiliaryFan1.setUpdateTime(new Date());
                                        auxiliaryFan1.setTagName(tagName);
                                        auxiliaryFan1.setValue(valueStr);
                                        auxiliaryFanList1.add(auxiliaryFan1);
                                        AuxiliaryFanHistory auxiliaryFanHistory1 = new AuxiliaryFanHistory();
                                        auxiliaryFanHistory1.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        auxiliaryFanHistory1.setTagName(tagName);
                                        auxiliaryFanHistory1.setValue(valueStr);
                                        auxiliaryFanHistory1.setUpdateTime(new Date());
                                        auxiliaryFanHistoryList1.add(auxiliaryFanHistory1);
                                        break;
                                    case  "局扇2":
                                        AuxiliaryFan auxiliaryFan2 = new AuxiliaryFan();
                                        auxiliaryFan2.setUpdateTime(new Date());
                                        auxiliaryFan2.setTagName(tagName);
                                        auxiliaryFan2.setValue(valueStr);
                                        auxiliaryFanList2.add(auxiliaryFan2);
                                        AuxiliaryFanHistory auxiliaryFanHistory2 = new AuxiliaryFanHistory();
                                        auxiliaryFanHistory2.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        auxiliaryFanHistory2.setTagName(tagName);
                                        auxiliaryFanHistory2.setValue(valueStr);
                                        auxiliaryFanHistory2.setUpdateTime(new Date());
                                        auxiliaryFanHistoryList2.add(auxiliaryFanHistory2);
                                        break;
                                    case  "局扇3":
                                        AuxiliaryFan auxiliaryFan3 = new AuxiliaryFan();
                                        auxiliaryFan3.setUpdateTime(new Date());
                                        auxiliaryFan3.setTagName(tagName);
                                        auxiliaryFan3.setValue(valueStr);
                                        auxiliaryFanList3.add(auxiliaryFan3);
                                        AuxiliaryFanHistory auxiliaryFanHistory3 = new AuxiliaryFanHistory();
                                        auxiliaryFanHistory3.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        auxiliaryFanHistory3.setTagName(tagName);
                                        auxiliaryFanHistory3.setValue(valueStr);
                                        auxiliaryFanHistory3.setUpdateTime(new Date());
                                        auxiliaryFanHistoryList3.add(auxiliaryFanHistory3);
                                        break;
                                    case  "局扇4":
                                        AuxiliaryFan auxiliaryFan4 = new AuxiliaryFan();
                                        auxiliaryFan4.setUpdateTime(new Date());
                                        auxiliaryFan4.setTagName(tagName);
                                        auxiliaryFan4.setValue(valueStr);
                                        auxiliaryFanList4.add(auxiliaryFan4);
                                        AuxiliaryFanHistory auxiliaryFanHistory4 = new AuxiliaryFanHistory();
                                        auxiliaryFanHistory4.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        auxiliaryFanHistory4.setTagName(tagName);
                                        auxiliaryFanHistory4.setValue(valueStr);
                                        auxiliaryFanHistory4.setUpdateTime(new Date());
                                        auxiliaryFanHistoryList4.add(auxiliaryFanHistory4);
                                        break;
                                    case  "制氮":
                                        //jhjsThreeHistoryMapper
                                        ProducingNitrogen producingNitrogen = new ProducingNitrogen();
                                        producingNitrogen.setUpdateTime(new Date());
                                        producingNitrogen.setTagName(tagName);
                                        producingNitrogen.setValue(valueStr);
                                        producingNitrogenList.add(producingNitrogen);
                                        ProducingNitrogenHistory producingNitrogenHistory = new ProducingNitrogenHistory();
                                        producingNitrogenHistory.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        producingNitrogenHistory.setTagName(tagName);
                                        producingNitrogenHistory.setValue(valueStr);
                                        producingNitrogenHistory.setUpdateTime(new Date());
                                        producingNitrogenHistoryList.add(producingNitrogenHistory);
                                        break;
                                    case  "1号主扇风机":
                                        //mainventilator1HistoryMapper
                                        MainventilatorOne mainventilatorOne = new MainventilatorOne();
                                        mainventilatorOne.setUpdateTime(new Date());
                                        mainventilatorOne.setTagName(tagName);
                                        mainventilatorOne.setValue(valueStr);
                                        mainventilatorOneList.add(mainventilatorOne);
                                        Mainventilator1History mainventilator1History = new Mainventilator1History();
                                        mainventilator1History.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        mainventilator1History.setTagName(tagName);
                                        mainventilator1History.setValue(valueStr);
                                        mainventilator1History.setUpdateTime(new Date());
                                        mainventilator1HistoryList.add(mainventilator1History);
                                        break;
                                    case  "2号主扇风机":
                                        //mainventilator1HistoryMapper
                                        MainventilatorOne mainventilatorOne1 = new MainventilatorOne();
                                        mainventilatorOne1.setUpdateTime(new Date());
                                        mainventilatorOne1.setTagName(tagName);
                                        mainventilatorOne1.setValue(valueStr);
                                        mainventilatorOneList1.add(mainventilatorOne1);
                                        Mainventilator1History mainventilator1History1 = new Mainventilator1History();
                                        mainventilator1History1.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        mainventilator1History1.setTagName(tagName);
                                        mainventilator1History1.setValue(valueStr);
                                        mainventilator1History1.setUpdateTime(new Date());
                                        mainventilator1HistoryList.add(mainventilator1History1);
                                        break;
                                    case  "皮带1":
                                        Belt belt1 = new Belt();
                                        belt1.setUpdateTime(new Date());
                                        belt1.setTagName(tagName);
                                        belt1.setValue(valueStr);
                                        beltList1.add(belt1);
                                        BeltHistory beltHistory1 = new BeltHistory();
                                        beltHistory1.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        beltHistory1.setTagName(tagName);
                                        beltHistory1.setValue(valueStr);
                                        beltHistory1.setUpdateTime(new Date());
                                        beltHistoryList1.add(beltHistory1);
                                        break;
                                    case  "皮带2":
                                        Belt belt2 = new Belt();
                                        belt2.setUpdateTime(new Date());
                                        belt2.setTagName(tagName);
                                        belt2.setValue(valueStr);
                                        beltList2.add(belt2);
                                        BeltHistory beltHistory2 = new BeltHistory();
                                        beltHistory2.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        beltHistory2.setTagName(tagName);
                                        beltHistory2.setValue(valueStr);
                                        beltHistory2.setUpdateTime(new Date());
                                        beltHistoryList2.add(beltHistory2);
                                        break;
                                    case  "皮带3":
                                        Belt belt3 = new Belt();
                                        belt3.setUpdateTime(new Date());
                                        belt3.setTagName(tagName);
                                        belt3.setValue(valueStr);
                                        beltList3.add(belt3);
                                        BeltHistory beltHistory3 = new BeltHistory();
                                        beltHistory3.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        beltHistory3.setTagName(tagName);
                                        beltHistory3.setValue(valueStr);
                                        beltHistory3.setUpdateTime(new Date());
                                        beltHistoryList3.add(beltHistory3);
                                        break;
                                    case  "皮带4":
                                        Belt belt4 = new Belt();
                                        belt4.setUpdateTime(new Date());
                                        belt4.setTagName(tagName);
                                        belt4.setValue(valueStr);
                                        beltList4.add(belt4);
                                        BeltHistory beltHistory4 = new BeltHistory();
                                        beltHistory4.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        beltHistory4.setTagName(tagName);
                                        beltHistory4.setValue(valueStr);
                                        beltHistory4.setUpdateTime(new Date());
                                        beltHistoryList4.add(beltHistory4);
                                        break;
                                    case  "地面变电所":
                                        Electricity electricity1 = new Electricity();
                                        electricity1.setUpdateTime(new Date());
                                        electricity1.setTagName(tagName);
                                        electricity1.setValue(valueStr);
                                        electricityList1.add(electricity1);
                                        ElectricityHistory electricityHistory = new ElectricityHistory();
                                        electricityHistory.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        electricityHistory.setTagName(tagName);
                                        electricityHistory.setValue(valueStr);
                                        electricityHistory.setUpdateTime(new Date());
                                        electricityHistoryList1.add(electricityHistory);
                                        break;
                                    case  "井下变电所":
                                        Electricity electricity2 = new Electricity();
                                        electricity2.setUpdateTime(new Date());
                                        electricity2.setTagName(tagName);
                                        electricity2.setValue(valueStr);
                                        electricityList2.add(electricity2);
                                        ElectricityHistory electricityHistory2 = new ElectricityHistory();
                                        electricityHistory2.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        electricityHistory2.setTagName(tagName);
                                        electricityHistory2.setValue(valueStr);
                                        electricityHistory2.setUpdateTime(new Date());
                                        electricityHistoryList2.add(electricityHistory2);
                                        break;
                                    case  "井下变电所低压一":
                                        Electricity electricity3 = new Electricity();
                                        electricity3.setUpdateTime(new Date());
                                        electricity3.setTagName(tagName);
                                        electricity3.setValue(valueStr);
                                        electricityList3.add(electricity3);
                                        ElectricityHistory electricityHistory3 = new ElectricityHistory();
                                        electricityHistory3.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        electricityHistory3.setTagName(tagName);
                                        electricityHistory3.setValue(valueStr);
                                        electricityHistory3.setUpdateTime(new Date());
                                        electricityHistoryList3.add(electricityHistory3);
                                        break;
                                    case  "井下变电所高压二":
                                        Electricity electricity4 = new Electricity();
                                        electricity4.setUpdateTime(new Date());
                                        electricity4.setTagName(tagName);
                                        electricity4.setValue(valueStr);
                                        electricityList4.add(electricity4);
                                        ElectricityHistory electricityHistory4 = new ElectricityHistory();
                                        electricityHistory4.setId(String.valueOf(snowflakeIdUtils.nextId()));
                                        electricityHistory4.setTagName(tagName);
                                        electricityHistory4.setValue(valueStr);
                                        electricityHistory4.setUpdateTime(new Date());
                                        electricityHistoryList4.add(electricityHistory4);
                                        break;
                                    default:
                                        break;
                                }
                            } else {
                                // 处理错误
                            }
                        }
                        switch (key){
                            case  "中央水泵房":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future99 = CompletableFuture.runAsync(() -> {
                                    if (centralpumphouseList.size() >0){
                                        centralpumphouseMapper.updateBatch(centralpumphouseList);
                                    }
                                });
                                futures.add(future99);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future98 = CompletableFuture.runAsync(() -> {
                                    if (centralpumphouseHistoryList.size() >0){
                                        centralpumphouseHistoryMapper.insertBatch(centralpumphouseHistoryList);
                                    }
                                });
                                futures.add(future98);
                                break;
                            case  "1-6瓦斯抽放泵":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future97 = CompletableFuture.runAsync(() -> {
                                    if (gasDrainagePumpRoomList.size() >0){
                                        gasDrainagePumpRoomMapper.updateBatch(gasDrainagePumpRoomList);
                                    }
                                });
                                futures.add(future97);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future96 = CompletableFuture.runAsync(() -> {
                                    if (gasDrainagePumpRoomHistoryList.size() >0){
                                        gasDrainagePumpRoomHistoryMapper.insertBatch(gasDrainagePumpRoomHistoryList);
                                    }
                                });
                                futures.add(future96);
                                break;
                            case  "7-10瓦斯抽放泵":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future95 = CompletableFuture.runAsync(() -> {
                                    if (gasDrainagePumpRoomList1.size() >0){
                                        gasDrainagePumpRoomMapper.updateBatch(gasDrainagePumpRoomList1);
                                    }
                                });
                                futures.add(future95);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future94 = CompletableFuture.runAsync(() -> {
                                    if (gasDrainagePumpRoomHistoryList1.size() >0){
                                        gasDrainagePumpRoomHistoryMapper.insertBatch(gasDrainagePumpRoomHistoryList1);
                                    }
                                });
                                futures.add(future94);
                                break;
                            case  "空压机":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
                                    if (aircompressorList.size() >0){
                                        aircompressorMapper.updateBatch(aircompressorList);
                                    }
                                });
                                futures.add(future2);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> {
                                    if (aircompressorHistoryList.size() >0){
                                        aircompressorHistoryMapper.insertBatch(aircompressorHistoryList);
                                    }
                                });
                                futures.add(future3);
                                break;
                            case  "制氮":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future14 = CompletableFuture.runAsync(() -> {
                                    if (producingNitrogenList.size() >0){
                                        producingNitrogenMapper.updateBatch(producingNitrogenList);
                                    }
                                });
                                futures.add(future14);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future15 = CompletableFuture.runAsync(() -> {
                                    if (producingNitrogenHistoryList.size() >0){
                                        producingNitrogenHistoryMapper.insertBatch(producingNitrogenHistoryList);
                                    }
                                });
                                futures.add(future15);
                                break;
                            case  "局扇1":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future16 = CompletableFuture.runAsync(() -> {
                                    if (auxiliaryFanList1.size() >0){
                                        auxiliaryFanMapper.updateBatch(auxiliaryFanList1);
                                    }
                                });
                                futures.add(future16);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future17 = CompletableFuture.runAsync(() -> {
                                    if (auxiliaryFanHistoryList1.size() >0){
                                        auxiliaryFanHistoryMapper.insertBatch(auxiliaryFanHistoryList1);
                                    }
                                });
                                futures.add(future17);
                                break;
                            case  "局扇2":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future106 = CompletableFuture.runAsync(() -> {
                                    if (auxiliaryFanList2.size() >0){
                                        auxiliaryFanMapper.updateBatch(auxiliaryFanList2);
                                    }
                                });
                                futures.add(future106);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future107 = CompletableFuture.runAsync(() -> {
                                    if (auxiliaryFanHistoryList2.size() >0){
                                        auxiliaryFanHistoryMapper.insertBatch(auxiliaryFanHistoryList2);
                                    }
                                });
                                futures.add(future107);
                                break;
                            case  "局扇3":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future108 = CompletableFuture.runAsync(() -> {
                                    if (auxiliaryFanList3.size() >0){
                                        auxiliaryFanMapper.updateBatch(auxiliaryFanList3);
                                    }
                                });
                                futures.add(future108);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future109 = CompletableFuture.runAsync(() -> {
                                    if (auxiliaryFanHistoryList3.size() >0){
                                        auxiliaryFanHistoryMapper.insertBatch(auxiliaryFanHistoryList3);
                                    }
                                });
                                futures.add(future109);
                                break;
                            case  "局扇4":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future110 = CompletableFuture.runAsync(() -> {
                                    if (auxiliaryFanList4.size() >0){
                                        auxiliaryFanMapper.updateBatch(auxiliaryFanList4);
                                    }
                                });
                                futures.add(future110);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future111 = CompletableFuture.runAsync(() -> {
                                    if (auxiliaryFanHistoryList4.size() >0){
                                        auxiliaryFanHistoryMapper.insertBatch(auxiliaryFanHistoryList4);
                                    }
                                });
                                futures.add(future111);
                                break;
                            case  "1号主扇风机":
                                //mainventilator1HistoryMapper
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future18 = CompletableFuture.runAsync(() -> {
                                    if (mainventilatorOneList.size() >0){
                                        mainventilatorOneMapper.updateBatch(mainventilatorOneList);
                                    }
                                });
                                futures.add(future18);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future19 = CompletableFuture.runAsync(() -> {
                                    if (mainventilator1HistoryList.size() >0){
                                        mainventilator1HistoryMapper.insertBatch(mainventilator1HistoryList);
                                    }
                                });
                                futures.add(future19);
                                break;
                            case  "2号主扇风机":
                                //mainventilator2HistoryMapper
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future20 = CompletableFuture.runAsync(() -> {
                                    if (mainventilatorOneList1.size() >0){
                                        mainventilatorOneMapper.updateBatch(mainventilatorOneList1);
                                    }
                                });
                                futures.add(future20);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future21 = CompletableFuture.runAsync(() -> {
                                    if (mainventilator1HistoryList1.size() >0){
                                        mainventilator1HistoryMapper.insertBatch(mainventilator1HistoryList1);
                                    }
                                });
                                futures.add(future21);
                                break;
                            case  "皮带":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future22 = CompletableFuture.runAsync(() -> {
                                    if (beltList1.size() >0){
                                        beltMapper.updateBelts(beltList1);
                                    }
                                });
                                futures.add(future22);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future23 = CompletableFuture.runAsync(() -> {
                                    if (beltHistoryList1.size() >0){
                                        beltHistoryMapper.insertBeltHistorys(beltHistoryList1);
                                    }
                                });
                                futures.add(future23);
                                break;
                            case  "皮带2":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future220 = CompletableFuture.runAsync(() -> {
                                    if (beltList2.size() >0){
                                        beltMapper.updateBelts(beltList2);
                                    }
                                });
                                futures.add(future220);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future221 = CompletableFuture.runAsync(() -> {
                                    if (beltHistoryList2.size() >0){
                                        beltHistoryMapper.insertBeltHistorys(beltHistoryList2);
                                    }
                                });
                                futures.add(future221);
                                break;
                            case  "皮带3":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future222 = CompletableFuture.runAsync(() -> {
                                    if (beltList3.size() >0){
                                        beltMapper.updateBelts(beltList3);
                                    }
                                });
                                futures.add(future222);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future223 = CompletableFuture.runAsync(() -> {
                                    if (beltHistoryList3.size() >0){
                                        beltHistoryMapper.insertBeltHistorys(beltHistoryList3);
                                    }
                                });
                                futures.add(future223);
                                break;
                            case  "皮带4":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future224 = CompletableFuture.runAsync(() -> {
                                    if (beltList4.size() >0){
                                        beltMapper.updateBelts(beltList4);
                                    }
                                });
                                futures.add(future224);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future225 = CompletableFuture.runAsync(() -> {
                                    if (beltHistoryList4.size() >0){
                                        beltHistoryMapper.insertBeltHistorys(beltHistoryList4);
                                    }
                                });
                                futures.add(future225);
                                break;
                            case  "地面变电所":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future24 = CompletableFuture.runAsync(() -> {
                                    if (electricityList1.size() >0){
                                        electricityMapper.updateBatch(electricityList1);
                                    }
                                });
                                futures.add(future24);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future25 = CompletableFuture.runAsync(() -> {
                                    if (electricityHistoryList1.size() >0){
                                        electricityHistoryMapper.insertBatch(electricityHistoryList1);
                                    }
                                });
                                futures.add(future25);
                                break;
                            case  "井下变电所":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future26 = CompletableFuture.runAsync(() -> {
                                    electricityMapper.updateBatch(electricityList2);
                                });
                                futures.add(future26);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future27 = CompletableFuture.runAsync(() -> {
                                    electricityHistoryMapper.insertBatch(electricityHistoryList2);
                                });
                                futures.add(future27);
                                break;
                            case  "井下变电所低压一":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future28 = CompletableFuture.runAsync(() -> {
                                    electricityMapper.updateBatch(electricityList3);
                                });
                                futures.add(future28);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future29 = CompletableFuture.runAsync(() -> {
                                    electricityHistoryMapper.insertBatch(electricityHistoryList3);
                                });
                                futures.add(future29);
                                break;
                            case  "井下变电所高压二":
                                // 使用 CompletableFuture 来异步执行 updateBelts 方法
                                CompletableFuture<Void> future30 = CompletableFuture.runAsync(() -> {
                                    electricityMapper.updateBatch(electricityList4);
                                });
                                futures.add(future30);
                                // 使用 CompletableFuture 来异步执行 insertBeltHistorys 方法
                                CompletableFuture<Void> future31 = CompletableFuture.runAsync(() -> {
                                    electricityHistoryMapper.insertBatch(electricityHistoryList4);
                                });
                                futures.add(future31);
                                break;
                            default:
                                break;
                        }
                        // 等待所有异步任务完成
                        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

                        // 在这里可以添加处理所有任务完成后的逻辑
                        // 例如，打印日志或执行其他操作

                        // 如果需要获取每个future的结果（虽然这里都是Void类型，不需要获取结果）
                        // 可以遍历namedFutures并调用get()方法，但要注意处理可能的异常
                        try {
                            allFutures.get(); // 这会阻塞直到所有任务完成
                        } catch (InterruptedException | ExecutionException e) {
                            e.printStackTrace();
                        }
                    }).exceptionally(ex -> {
                        // 处理异常
                        ex.printStackTrace();
                        return null;
                    }).get();
                    //System.out.println("$$$$$$$$$$$$$$$$"+ (System.currentTimeMillis()-start) +"$$$$$$"+list.size());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获得key名称
     *
     * @param  path csv位置
     */
    private List<String> getCsvName(String path) {
        String csvFile = path;
        String [] line ;
        List<String> column1List = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(csvFile), "GBK"));
             CSVReader csvReader = new CSVReader(reader)) {
            // 读取文件头行
            String[] header = csvReader.readNext();
            // 找到第一列
            int column1Index =-1;
            for (int i = 0; i < header.length; i++) {
                if (header[i].equals("Tag Name")) {
                    column1Index = i;
                }
            }
            // 读取每一行数据
            while ((line = csvReader.readNext()) != null) {
                // 提取第数据
                if (column1Index != -1) {
                    column1List.add(line[column1Index]);
                }

            }
        } catch (Exception e) {

            e.printStackTrace();

        }
        return column1List;
    }
    /**
     * 自定义订阅监听
     */
    private class CustomSubscriptionListener implements UaSubscriptionManager.SubscriptionListener {

        private OpcUaClient client;

        CustomSubscriptionListener(OpcUaClient client) {
            this.client = client;
        }

        public void onKeepAlive(UaSubscription subscription, DateTime publishTime) {
//            System.out.println("onKeepAlive");
        }

        public void onStatusChanged(UaSubscription subscription, StatusCode status) {
//            System.out.println("onStatusChanged");
        }

        public void onPublishFailure(UaException exception) {
//            System.out.println("onPublishFailure");
        }

        public void onNotificationDataLost(UaSubscription subscription) {
//            System.out.println("onNotificationDataLost");
        }

        /**
         * 重连时 尝试恢复之前的订阅失败时 会调用此方法
         * @param uaSubscription 订阅
         * @param statusCode 状态
         */
        public void onSubscriptionTransferFailed(UaSubscription uaSubscription, StatusCode statusCode) {
            System.out.println("恢复订阅失败 需要重新订阅");
            //在回调方法中重新订阅
            //handlerNode(client,keyToSubscribe);
        }
    }

    /**
     * 批量订阅
     *
     * @param client
     * @throws Exception
     */
    private  void managedSubscriptionEvent(OpcUaClient client,List<String> list)  throws Exception {
//        final CountDownLatch eventLatch = new CountDownLatch(1);
//
//        //添加订阅监听器，用于处理断线重连后的订阅问题
//        client.getSubscriptionManager().addSubscriptionListener(new FolderCreationRunner.CustomSubscriptionListener(client));

        //处理订阅业务
        handlerNode(client,list);

//        //持续监听
//        eventLatch.await();
    }
    public  void readAccessDiMianFenZhan(String sourcePath) throws Exception {
        //String[] str={"AutoID", "Code", "Name", "Address","HoleLevel","A1","A2","A3","A4","A5","A6","State","GIS_X","GIS_Y","GraphShow"};
        String mdbPath = sourcePath;
        String mdbSql = "SELECT * FROM DiMianFenZhan";
        List<String> mdbList = Arrays.asList("AutoID", "Code", "Name", "Address","HoleLevel","A1","A2","A3","A4","A5","A6","State","GIS_X","GIS_Y","GraphShow");
        // 假设 MdbUtils 是你项目中定义的类，用于解析 MDB 文件并执行 SQL 查询
        List<Map<String, Object>> selectList = MdbUtils.resolverMdb(mdbPath, mdbSql, mdbList);
        for (Map<String, Object> row : selectList) {
            Dimianfenzhan dimianfenzhan=new Dimianfenzhan();
            dimianfenzhan.setAutoID((int) Double.parseDouble(String.valueOf(row.get("AutoID"))));
            dimianfenzhan.setCode(String.valueOf(row.get("Code")));
            dimianfenzhan.setName(String.valueOf(row.get("Name")));
            dimianfenzhan.setAddress(String.valueOf( row.get("Address")));
            dimianfenzhan.setHoleLevel(Float.valueOf(String.valueOf(row.get("HoleLevel"))));
            dimianfenzhan.setA1(Float.valueOf(String.valueOf(row.get("A1"))));
            dimianfenzhan.setA2(Float.valueOf(String.valueOf(row.get("A2"))));
            dimianfenzhan.setA3(Float.valueOf(String.valueOf(row.get("A3"))));
            dimianfenzhan.setA4(Float.valueOf(String.valueOf(row.get("A4"))));
            dimianfenzhan.setA5(Float.valueOf(String.valueOf(row.get("A5"))));
            dimianfenzhan.setA6(Float.valueOf(String.valueOf(row.get("A6"))));
            dimianfenzhan.setState(String.valueOf( row.get("State")));
            dimianfenzhan.setGisX((int) Double.parseDouble(String.valueOf(row.get("GIS_X"))));
            dimianfenzhan.setGisY((int) Double.parseDouble(String.valueOf(row.get("GIS_Y"))));
            dimianfenzhan.setGraphShow((int) Double.parseDouble(String.valueOf(row.get("GraphShow"))));
            dimianfenzhan.setUDateTime(new Date());
            if (dimianfenzhanService.selectDimianfenzhanByCode(dimianfenzhan.getCode()) !=null){
                dimianfenzhan.setAutoID(dimianfenzhanService.selectDimianfenzhanByCode(dimianfenzhan.getCode()).getAutoID());
                dimianfenzhanService.updateDimianfenzhan(dimianfenzhan);
            }else {
                dimianfenzhanService.insertDimianfenzhan(dimianfenzhan);
            }
            DimianfenzhanHistory dimianfenzhanHistory=new DimianfenzhanHistory();
            BeanUtils.copyProperties(dimianfenzhan,dimianfenzhanHistory);
            dimianfenzhanHistory.setId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
            dimianfenzhanHistoryServiceService.insertDimianfenzhanHistory(dimianfenzhanHistory);
        }
    }
    public  void readAccessDiMian(String sourcePath) throws Exception {
        String mdbPath = sourcePath;
        String mdbSql = "SELECT * FROM DiMian";
        List<String> mdbList = Arrays.asList("AutoID", "Code", "uDateTime", "maiShen","maiShenSta","WaterLevel","shuiWen","shuiWenSta","DianYa","DianYaSta");
        List<Map<String, Object>> selectList = MdbUtils.resolverMdb(mdbPath, mdbSql, mdbList);
        for (Map<String, Object> row : selectList) {
            Dimian dimian=new Dimian();
            dimian.setAutoID((int) Double.parseDouble(String.valueOf(row.get("AutoID"))));
            dimian.setCode(String.valueOf(row.get("Code")));
            dimian.setUDateTime((Date) row.get("uDateTime"));
            dimian.setMaiShen(Float.valueOf(String.valueOf(row.get("maiShen"))));
            dimian.setMaiShenSta(String.valueOf(row.get("maiShenSta")));
            dimian.setWaterLevel(Float.valueOf(String.valueOf(row.get("WaterLevel"))));
            dimian.setShuiWen(Float.valueOf(String.valueOf(row.get("shuiWen"))));
            dimian.setShuiWenSta(String.valueOf(row.get("shuiWenSta")));
            dimian.setDianYa(Float.valueOf(String.valueOf(row.get("DianYa"))));
            dimian.setDianYaSta(String.valueOf(row.get("DianYaSta")));
            if (dimianService.selectDimianByCode(dimian.getCode()) !=null){
                dimian.setAutoID(dimianService.selectDimianByCode(dimian.getCode()).getAutoID());
                dimianService.updateDimian(dimian);
            }else {
                dimianService.insertDimian(dimian);
            }
            DimianHistory dimianHistory=new DimianHistory();
            BeanUtils.copyProperties(dimian,dimianHistory);
            dimianHistory.setId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
            dimianHistoryService.insertDimianHistory(dimianHistory);
        }
    }
    public  void readAccessJingxiaFenZhan(String sourcePath) throws Exception {
        //String[] str={"AutoID", "Code", "Name", "Address","HoleLevel","A1","A2","A3","A4","A5","A6","State","GIS_X","GIS_Y","GraphShow"};
        String mdbPath = sourcePath;
        String mdbSql = "SELECT * FROM JingXiaFenZhan";
        List<String> mdbList = Arrays.asList("AutoID", "Code", "ChannelNO", "Name","MeasureName","MeasureUnit" ,"A1","A2","A3","A4","A5","A6","State","GIS_X","GIS_Y","GraphShow");
        List<Map<String, Object>> selectList = MdbUtils.resolverMdb(mdbPath, mdbSql, mdbList);
        for (Map<String, Object> row : selectList) {
            Jingxiafenzhan jingxiafenzhan=new Jingxiafenzhan();
            jingxiafenzhan.setAutoID((int) Double.parseDouble(String.valueOf(row.get("AutoID"))));
            jingxiafenzhan.setCode(String.valueOf(row.get("Code")));
            jingxiafenzhan.setName(String.valueOf(row.get("Name")));
            jingxiafenzhan.setChannelNO((int) Double.parseDouble(String.valueOf(row.get("ChannelNO"))));
            jingxiafenzhan.setMeasureName(String.valueOf( row.get("MeasureName")));
            jingxiafenzhan.setMeasureUnit(String.valueOf(row.get("MeasureUnit")));
            jingxiafenzhan.setA1(Float.valueOf(String.valueOf(row.get("A1"))));
            jingxiafenzhan.setA2(Float.valueOf(String.valueOf(row.get("A2"))));
            jingxiafenzhan.setA3(Float.valueOf(String.valueOf(row.get("A3"))));
            jingxiafenzhan.setA4(Float.valueOf(String.valueOf(row.get("A4"))));
            jingxiafenzhan.setA5(Float.valueOf(String.valueOf(row.get("A5"))));
            jingxiafenzhan.setA6(Float.valueOf(String.valueOf(row.get("A6"))));
            jingxiafenzhan.setState(String.valueOf( row.get("State")));
            jingxiafenzhan.setGisX((int) Double.parseDouble(String.valueOf(row.get("GIS_X"))));
            jingxiafenzhan.setGisY((int) Double.parseDouble(String.valueOf(row.get("GIS_Y"))));
            jingxiafenzhan.setGraphShow((int) Double.parseDouble(String.valueOf(row.get("GraphShow"))));
            jingxiafenzhan.setUDateTime(new Date());
            if (jingxiafenzhanService.selectJingxiafenzhanByCode(jingxiafenzhan.getCode()) !=null){
                jingxiafenzhan.setAutoID(jingxiafenzhanService.selectJingxiafenzhanByCode(jingxiafenzhan.getCode()).getAutoID());
                jingxiafenzhanService.updateJingxiafenzhan(jingxiafenzhan);
            }else {
                jingxiafenzhanService.insertJingxiafenzhan(jingxiafenzhan);
            }
            JingxiafenzhanHistory jingxiafenzhanHistory=new JingxiafenzhanHistory();
            BeanUtils.copyProperties(jingxiafenzhan,jingxiafenzhanHistory);
            jingxiafenzhanHistory.setId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
            jingxiafenzhanHistoryService.insertJingxiafenzhanHistory(jingxiafenzhanHistory);
        }
    }
    public  void readAccessJingxia(String sourcePath) throws Exception {
        String mdbPath = sourcePath;
        String mdbSql = "SELECT * FROM JingXia";
        List<String> mdbList = Arrays.asList("AutoID", "Code", "Channel","uDateTime", "Address","MeasureName","MeasureUnit","Value","ValueState");
        // 假设 MdbUtils 是你项目中定义的类，用于解析 MDB 文件并执行 SQL 查询
        List<Map<String, Object>> list = MdbUtils.resolverMdb(mdbPath, mdbSql, mdbList);
        for (Map<String, Object> row : list) {
            Jingxia jingxia=new Jingxia();
            jingxia.setAutoID((int) Double.parseDouble(String.valueOf(row.get("AutoID"))));
            jingxia.setCode(String.valueOf(row.get("Code")));
            jingxia.setUDateTime((Date) row.get("uDateTime"));
            jingxia.setChannel((int) Double.parseDouble(String.valueOf(row.get("Channel"))));
            jingxia.setAddress(String.valueOf(row.get("Address")));
            jingxia.setMeasureName(String.valueOf(row.get("MeasureName")));
            jingxia.setMeasureUnit(String.valueOf(row.get("MeasureUnit")));
            jingxia.setValueState(String.valueOf(row.get("ValueState")));
            jingxia.setValue(Float.valueOf(String.valueOf(row.get("Value"))));
            if (jingxiaService.selectJingxiaByCode(jingxia.getCode()) !=null){
                jingxia.setAutoID(jingxiaService.selectJingxiaByCode(jingxia.getCode()).getAutoID());
                jingxiaService.updateJingxia(jingxia);
            }else {
                jingxiaService.insertJingxia(jingxia);
            }
            JingxiaHistory jingxiaHistory=new JingxiaHistory();
            BeanUtils.copyProperties(jingxia,jingxiaHistory);
            jingxiaHistory.setId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
            jingxiaHistoryService.insertJingxiaHistory(jingxiaHistory);
        }
    }
    public  boolean deleteFileWithRetry(String filePath, int maxRetries, int delay, TimeUnit unit) {
        int attempt = 0;
        while (attempt < maxRetries) {
            try {
                Files.delete(Paths.get(filePath));
                return true; // 文件成功删除
            } catch (FileSystemException e) {
                // 捕获到文件系统异常，表示文件可能正在被使用
                attempt++;
                if (attempt < maxRetries) {
                    try {
                        // 等待指定的时间后再重试
                        unit.sleep(delay);
                    } catch (InterruptedException ie) {
                        // 如果当前线程在等待期间被中断，可以选择记录日志、重新设置中断状态或抛出异常
                        Thread.currentThread().interrupt();
                        return false; // 由于中断，放弃删除文件
                    }
                } else {
                    // 达到最大重试次数，返回false表示文件未删除
                    return false;
                }
            } catch (IOException e) {
                // 处理其他IO异常，如文件不存在等（在这个场景中可能不太常见）
                e.printStackTrace();
                return false; // 由于其他IO错误，放弃删除文件
            }
        }
        return false; // 如果循环结束都没有成功删除文件，则返回false
    }
    public static OpcUaClient createClientNewEndpoint(String endPointUrl, String username, String password) {
        System.out.println(endPointUrl);
        IdentityProvider identityProvider = new AnonymousProvider();
        if (!StringUtils.isEmpty(username) || !StringUtils.isEmpty(password)) {
            identityProvider = new UsernameProvider(username, password);
        }
        try {
            Function<List<EndpointDescription>, Optional<EndpointDescription>> selectEndpoint = endpoints -> {
                final Optional<EndpointDescription> endpoint = endpoints
                        .stream()
                        //SecurityPolicy.Basic256
                        .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
                        .findFirst();
                EndpointDescription newEndpoint = new EndpointDescription(endPointUrl, endpoint.get().getServer(), endpoint.get().getServerCertificate(),
                        endpoint.get().getSecurityMode(), endpoint.get().getSecurityPolicyUri(), endpoint.get().getUserIdentityTokens(),
                        endpoint.get().getTransportProfileUri(), endpoint.get().getSecurityLevel());
                return Optional.of(newEndpoint);
            };
            IdentityProvider finalIdentityProvider = identityProvider;
            OpcUaClient opcClient = OpcUaClient.create(endPointUrl,
                    selectEndpoint,
                    configBuilder -> configBuilder
                            .setApplicationName(LocalizedText.english("plc"))
                            .setApplicationUri("urn:eclipse:milo:examples:client")
                            //访问方式
                            .setIdentityProvider(finalIdentityProvider)
                            .setRequestTimeout(UInteger.valueOf(10000))
                            .build()
            );
            opcClient.connect().get();
            return opcClient;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

